package org.framework.common.ext.util.datasource;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.ResourceEntityResolver;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 动态数据源
 * <p>描述: </p>
 * <p>Company: Professional</p>
 * @author chanlong(陈龙)
 * @date 2016年1月13日 上午10:28:28
 * @version 1.0.2016
 */
public class DynamicDataSource extends AbstractRoutingDataSource implements ApplicationContextAware {

	private Map<Object, Object> targetDataSources;
	
	private ConfigurableApplicationContext context = null;
	
	/**
	 * 构造函数.
	 * @author chanlong(陈龙)
	 * @date 2016年1月14日 下午4:57:20
	 */
	public DynamicDataSource() {
		targetDataSources = new HashMap<Object, Object>();
	}

	/**
	 * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
	 * @author chanlong(陈龙)
	 * @date 2016年1月13日 上午10:32:46
	 */
	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException {
		this.context = (ConfigurableApplicationContext) context;
	}
	
	/**
	 * 添加数据源.
	 * @param key
	 * @param dataSource
	 * @author chanlong(陈龙)
	 * @date 2016年1月14日 下午3:07:41
	 */
	public void addDataSource(Object key, Object dataSource){
		this.targetDataSources.put(key, dataSource);
		
		setTargetDataSources(this.targetDataSources);
	}
	
	/**
	 * 是否已有数据源.
	 * @param key
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年2月7日 下午6:46:01
	 */
	public boolean hasDataSource(Object key){
		return targetDataSources.containsKey(key);
	}
	
	public void setDataSource(final String dataSource){
		DynamicDataSourceHolder.setDataSource(dataSource);
	}
	
	public String getDataSource(){
		return String.valueOf(determineCurrentLookupKey());
	}
	
	/**
	 * 加载数据源bean的实例.
	 * @param filename
	 * @author chanlong(陈龙)
	 * @date 2016年1月13日 上午10:38:59
	 */
	public void loaderBean(String filename) {
		XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) context.getBeanFactory());
		reader.setResourceLoader(context);
		reader.setEntityResolver(new ResourceEntityResolver(context));
		try {
			reader.loadBeanDefinitions(context.getResources(filename));
		} catch (BeansException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 从当前线程中获取数据源名称.
	 * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey()
	 * @author chanlong(陈龙)
	 * @date 2016年1月13日 上午10:28:24
	 */
	@Override
	protected Object determineCurrentLookupKey() {
		String dbsource = DynamicDataSourceHolder.getDataSource();
		return dbsource == null ? "default" : dbsource;
	}

	/**
	 * @see org.framework.common.util.datasource.AbstractRoutingDataSource#setTargetDataSources(java.util.Map)
	 * @author chanlong(陈龙)
	 * @date 2016年1月14日 下午3:10:48
	 */
	@Override
	public void setTargetDataSources(Map<Object, Object> targetDataSources) {
		super.setTargetDataSources(targetDataSources);
		super.afterPropertiesSet();
	}
}
